﻿// ==UserScript==
// @name WME Mass Delete
// @description This script selects all of the unknown road type segments.
// @namespace http://www.leafcreations.org
// @grant none
// @version 1.1.4
// @include https://*.waze.com/editor/*
// @include https://*.waze.com/map-editor/*
// @include https://*.waze.com/beta_editor/*
// ==/UserScript==

// How To Use:
// 1) Install this script:
//      A) Compatible with Greasemonkey (Firefox) and Tampermonkey (Chrome)
//      B) Chrome > Tools > Extensions
// 2) Refresh Waze (if open)
// 3) Click Permamaps tab and select map service

LCMassDelete = {};
LCMassDelete.name = "MassDelete";
LCMassDelete.id = "MassDelete";
LCMassDelete.version = "1.1.4";

LCMassDelete.user = '';
LCMassDelete.userRank = 0;

LCMassDelete.enums = {};
LCMassDelete.enums.roadDirections = {
    Unknown: 0,
    OneWayAB: 1,
    OneWayBA: 2,
    Twoway: 3,
    UnnamedSegment: 4
}

LCMassDelete.enums.userRanks = {
    Level1: 0,
    Level2: 1,
    Level3: 2,
    Level4: 3,
    Level5: 4
}
LCMassDelete.enums.roadTypes = {
    Street: 1,
    DirtRoad: 8,
    PrivateRoad: 17,
    Railroad: 18,
    ParkingLotRoad: 20,    
    ServiceRoad: 21
}

// ******************************************************************************
// INITIATES THE USER SCRIPT - CALLED AT LIST LINE OF SCRIPT
// ******************************************************************************
LCMassDelete.bootstrap = function () {
    var bGreasemonkeyServiceDefined = false;

    try {
        bGreasemonkeyServiceDefined = (typeof Components.interfaces.gmIGreasemonkeyService === "object");
    }
    catch (err) { /* Ignore */ }

    if (typeof unsafeWindow === "undefined" || !bGreasemonkeyServiceDefined) {
        unsafeWindow = (function () {
            var dummyElem = document.createElement('p');
            dummyElem.setAttribute('onclick', 'return window;');
            return dummyElem.onclick();
        })();
    }

    /* begin running the code! */
    setTimeout(LCMassDelete.initialize, 500);
}

// ******************************************************************************
// HELPER FUNCTIONS
// ******************************************************************************
LCMassDelete.helper = {};
LCMassDelete.helper.getElementsByClassName = function (classname, node) {
    if (!node) node = document.getElementsByTagName("body")[0];
    var a = [];
    var re = new RegExp('\\b' + classname + '\\b');
    var els = node.getElementsByTagName("*");
    for (var i = 0, j = els.length; i < j; i++)
        if (re.test(els[i].className)) a.push(els[i]);
    return a;
}
LCMassDelete.helper.getId = function (node) {
    return document.getElementById(node);
}
LCMassDelete.helper.getQueryString = function (link, name) {
    var pos = link.indexOf(name + '=') + name.length + 1;
    var len = link.substr(pos).indexOf('&');
    return link.substr(pos, len);
}

// ******************************************************************************
// HTML HELPER FUNCTIONS
// ******************************************************************************
LCMassDelete.html = {};
LCMassDelete.html.createSection = function (name) {
    var section = document.createElement('p');
    section.name = name;
    section.style.fontSize = '10px';

    return section
}
LCMassDelete.html.createButton = function (name) {
    var item = document.createElement('button');
    item.innerHTML = name;
    item.style.width = '150px';

    return item
}
LCMassDelete.html.createSelector = function (rType, rId, rName, rValue, rText, isChecked) {
    var _isChecked = ''

    if (isChecked == true) {
        _isChecked = 'checked';
    }

    return '<input type="' + rType + '" id="' + rId + '" name="' + rName + '" value="' + rValue + '"' + _isChecked + ' /> ' + rText + '&nbsp;'
}
// ******************************************************************************

LCMassDelete.events = {};
LCMassDelete.events.massSelect = function () {
    var obj = wazeModel.segments.objects
    var foundSegs = new Array();

    var s1 = LCMassDelete.helper.getId('rType');
    var s2 = LCMassDelete.helper.getId('rDirection');
    var s3 = LCMassDelete.helper.getId('sLimit');

    var c1 = LCMassDelete.helper.getId('c1_islocked');
    var c2 = LCMassDelete.helper.getId('c1_disableAlert');

    var rType = s1.options[s1.selectedIndex].value;
    var rDirection = s2.options[s2.selectedIndex].value;
    var sLimit = s3.options[s3.selectedIndex].value;

    var iCount = 0;
    
    for (var key in obj) {
        var o = obj[key];

        if (o.getLockRank() <= LCMassDelete.userRank) {

            if (!LCMassDelete.events.observeLock(c1.checked, o.attributes.locked)) {

                if (o.onScreen()) {

                    if (o.arePropertiesEditable()) {

                        if (!o.isDeleted()) {

                            if (parseInt(o.attributes.roadType) == parseInt(rType)) {

                                if (!LCMassDelete.events.IsPartialNode(o.attributes.fromNodeID) && !LCMassDelete.events.IsPartialNode(o.attributes.toNodeID)) {

                                    if (parseInt(o.getDirection()) == parseInt(rDirection)) {

                                        if (rType != 18) {
                                            var streets = new Array();
                                            streets = o.getAddress();

                                            if (streets.street.name != null) {
                                                foundSegs.push(wazeModel.segments.objects[o.fid]);
                                                iCount++;
                                            }
                                        }
                                        else {
                                            foundSegs.push(wazeModel.segments.objects[o.fid]);
                                            iCount++;
                                        }
                                    }
                                    if (parseInt(rDirection) == LCMassDelete.enums.roadDirections.UnnamedSegment) {
                                        if (o.attributes.primaryStreetID == null) {
                                            foundSegs.push(wazeModel.segments.objects[o.fid]);
                                            iCount++;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }                
            }
        }
        if (iCount == sLimit) {
            break;
        }

    }

    if (foundSegs.length > 0) {
        if (!c2.checked) { alert('There are ' + foundSegs.length + ' segments that have been selected.') };
        selectionManager.selectControl.selectMultiple(foundSegs);        
    }
}

LCMassDelete.events.selectUnknown = function () {
    var obj = wazeModel.segments.objects
    var foundSegs = new Array();

    var s1 = LCMassDelete.helper.getId('rType');
    var s2 = LCMassDelete.helper.getId('rDirection');
    var s3 = LCMassDelete.helper.getId('sLimit');

    var rType = s1.options[s1.selectedIndex].value;
    var rDirection = s2.options[s2.selectedIndex].value;
    var sLimit = s3.options[s3.selectedIndex].value;

    var iCount = 0

    for (var key in obj) {
        var o = obj[key];


        if (o.getLockRank() <= LCMassDelete.userRank) {

            if (o.onScreen()) {

                if (o.arePropertiesEditable()) {

                    if (!o.isDeleted()) {

                        if (parseInt(o.attributes.roadType) == parseInt(rType)) {
                                                           
                            if (!LCMassDelete.events.IsPartialNode(o.attributes.fromNodeID) && !LCMassDelete.events.IsPartialNode(o.attributes.toNodeID)) {

                                if (parseInt(o.getDirection()) == parseInt(rDirection)) {

                                    if (rType != 18) {
                                        var streets = new Array();
                                        streets = o.getAddress();

                                        if (streets.street.name === null) {
                                            foundSegs.push(wazeModel.segments.objects[o.fid]);
                                            iCount++;
                                        }
                                    }
                                    else {
                                        foundSegs.push(wazeModel.segments.objects[o.fid]);
                                        iCount++;
                                    }
                                }
                                if (parseInt(rDirection) == LCMassDelete.enums.roadDirections.UnnamedSegment) {
                                    if (o.attributes.primaryStreetID == null) {
                                        foundSegs.push(wazeModel.segments.objects[o.fid]);
                                        iCount++;
                                    }
                                }
                            }                            
                        }
                    }
                }
            }
        }
        if (iCount == sLimit) {
            break;
        }

    }

    if (foundSegs.length > 0) {
        alert('There are ' + foundSegs.length + ' segments that have been selected for deletion.');        
        wazeModel.deleteSegments(foundSegs);
    }
}

LCMassDelete.events.IsPartialNode = function (nodeID) {

    if (nodeID == null) { return false; }

    var node = wazeModel.nodes.get(nodeID);    

    for (var key in node.data) {
        if (key === 'partial') return true;
    }
}

LCMassDelete.events.observeLock = function (isChecked, isLocked) {

    if (!isChecked) { return false };

    if (isLocked) { return true };

    return false;
}

LCMassDelete.events.selectCameras = function () {

    var c1 = LCMassDelete.helper.getId('cType');
    var c2 = LCMassDelete.helper.getId('cDays');

    var cType = c1.options[c1.selectedIndex].value;
    var cDays = c2.options[c2.selectedIndex].value;

    var obj = wazeModel.cameras.objects
    var foundSegs = new Array();

    var iCount = 0

    var today = new Date()

    for (var key in obj) {
        var o = obj[key];

        if (o.onScreen()) {

            if (!o.attributes.validated) {

                if (o.attributes.type = cType) {

                    if (!o.isDeleted()) {

                        var date = new Date(o.attributes.createdOn)

                        var tDay = today.getDate();
                        var cDay = date.getDate();

                        console.log(Math.abs(tDay - cDay))
                        if (Math.abs(tDay - cDay) >= cDays
                            ) {
                            foundSegs.push(wazeModel.cameras.objects[o.fid]);
                        }
                    }
                }
            }
        }
        if (iCount == sLimit) {
            break;
        }

    }

    if (foundSegs.length > 0) {
        alert('There are ' + foundSegs.length + ' segments that have been selected for deletion.');
        wazeModel.deleteObjects(foundSegs);
    }
}

// ******************************************************************************
// BUILDS THE TAB AND ITS CONTENT
// ******************************************************************************
LCMassDelete.initialize = function () {

    // access the bits of WME we need
    Waze = unsafeWindow.Waze;
    wazeMap = unsafeWindow.wazeMap;
    wazeModel = unsafeWindow.wazeModel;
    loginManager = unsafeWindow.loginManager;
    selectionManager = unsafeWindow.selectionManager;

    // add new box to left of the map
    var addon = document.createElement('div');
    addon.id = LCMassDelete.id;
    addon.innerHTML = '<a href="http://userscripts.org/scripts/show/165345" target="_blank">MassDelete</a> v' + LCMassDelete.version;

    //
    // -- START ADD OF SERVICES
    //    

    var section = document.createElement('p');
    section.innerHTML = '<h5>Roads</h5>';
    addon.appendChild(section);

    var section = document.createElement('p');
    section.innerHTML = 'Select the Road Type: <br>' +
                        '<select name="rType" id="rType">' +
                        '<option value="1">Street</option>' +
                        '<option value="17">Private Road</option>' +
                        '<option value="20">Parking Lot Road</option>' +
                        '<option value="8">Dirt road / 4x4 Trail</option>' +
                        '<option value="21">Service Road</option>' +
                        '<option value="18">Railroad</option>' +
                        '</select>'
    addon.appendChild(section);

    var section = document.createElement('p');
    section.innerHTML = 'Select the Direction: <br>' +
                        '<select name="rDirection" id="rDirection">' +
                        '<option value="0">Unknown</option>' +
                        '<option value="1">One Way (A - B)</option>' +
                        '<option value="2">One Way (B - A)</option>' +
                        '<option value="3">Two-way</option>' +
                        '<option value="4">Unnamed segment</option>' +
                        '</select>'
    addon.appendChild(section);

    var section = document.createElement('p');
    section.innerHTML = 'Selection Limit: <br>' +
                        '<select name="sLimit" id="sLimit">' +
                        '<option value="5">5</option>' +
                        '<option value="9" selected="selected">9</option>' +
                        '<option value="15">15</option>' +
                        '<option value="20">20</option>' +
                        '<option value="50">50</option>' +
                        '<option value="100">100</option>' +
                        '</select>'
    addon.appendChild(section);

    var section = document.createElement('p');
    section.innerHTML = 'Options: <br>' +
                        LCMassDelete.html.createSelector('checkbox', 'c1_islocked', 'isLocked', 'n', 'Observe "locked" flag', false) + '<br>' +
                        LCMassDelete.html.createSelector('checkbox', 'c1_disableAlert', 'disableAlert', 'n', 'Disable message box', true);
    addon.appendChild(section);

    var btn = LCMassDelete.html.createButton('Delete Roads');
    btn.onclick = function () { LCMassDelete.events.selectUnknown() };
    addon.appendChild(btn);

    var btn = LCMassDelete.html.createButton('Select Roads');
    btn.onclick = function () { LCMassDelete.events.massSelect() };
    addon.appendChild(btn);

    var section = document.createElement('p');
    section.innerHTML = '<h5>Cameras</h5>';
    addon.appendChild(section);

    var section = document.createElement('p');
    section.innerHTML = 'Camera Type: <br>' +
                        '<select name="cType" id="cType">' +
                        '<option value="2">Speed Camera</option>' +
                        '<option value="3" selected="selected">Dummy</option>' +
                        '<option value="4">Red light Camera</option>' +
                        '</select>'
    addon.appendChild(section);

    var section = document.createElement('p');
    section.innerHTML = 'Days Old: <br>' +
                        '<select name="cDays" id="cDays">' +
                        '<option value="5">5</option>' +
                        '<option value="9" selected="selected">9</option>' +
                        '<option value="14">14</option>' +
                        '</select>'
    addon.appendChild(section);

    var btn = LCMassDelete.html.createButton('Delete Cameras');
    btn.onclick = function () { LCMassDelete.events.selectCameras() };
    addon.appendChild(btn);

    //
    // -- END ADD OF SERVICES
    //

    //
    // -- START ADD USER TAB
    //

    var userTabs = LCMassDelete.helper.getId('user-tabs');
    var navTabs = LCMassDelete.helper.getElementsByClassName('nav-tabs', userTabs)[0];
    var tabContent = LCMassDelete.helper.getElementsByClassName('tab-content', userTabs)[0];

    newtab = document.createElement('li');
    newtab.innerHTML = '<a href="#sidepanel-' + LCMassDelete.id + '" data-toggle="tab">' + LCMassDelete.name + '</a>';
    navTabs.appendChild(newtab);

    addon.id = 'sidepanel-' + LCMassDelete.id;
    addon.className = "tab-pane";
    tabContent.appendChild(addon);

    //
    // -- END ADD USER TAB
    //    

    LCMassDelete.user = loginManager.user.userName;
    LCMassDelete.userRank = loginManager.user.rank;

}
// ******************************************************************************

// ******************************************************************************
// MASSDELETE IS A GO!
// ******************************************************************************
LCMassDelete.bootstrap();
// ******************************************************************************